import {createContext, useContext, useEffect, useReducer} from 'react'
import {randInt} from 'three/src/math/MathUtils.js'
import {insertCoin, onTikTokLiveEvent} from 'playroomkit'
import {DEBUG_MODE} from '../App.jsx'

const GAME_TIME = 60
const GREEN_MEN_COUNT = 8
const GREEN_MEN_RESET_TIME = 3000
const GREEN_MEN_RESET_ATTACK_TIME = 1800

const GREEN_MEN_NAMES = [
  '杨征',
  '谢剑良',
  '谢永利',
  '李士明',
  '贾进',
  '王明胜',
  '杨光耀',
  '马宁',
  '李鹏',
  '刘朕中',
  '三三',
  '四四',
  '李增松',
  '陈常召',
  '李艳峰',
  '窦岩',
  '翟传龙',
  '艾晨阳',
  '李娜',
  '乔琳琳',
  '邢志军',
  '薛松',
  '王西晗',
  '徐天昊',
  '张济磊',
  '王慎波',
  '吴桂梅',
  '周长海',
  '安坤',
  '张志恒',
  '姚永花',
  '孙利军',
  '彭涛',
  '彭祥龙',
  '陈宁宁',
  '田朝瑜',
  '包汉钰',
  '李贵丽',
  '代文亮',
  '张学锋',
  '陈安冬',
  '董维超',
  '姚副娟',
  '陆欣伟',
  '马秀玲',
  '王德祥',
  '刘方',
  '李庆振',
  '唐顺程',
  '李长智',
  '周磊磊',
  '韩政',
  '刘庆珂',
  '闫煜鑫',
  '李亚洲',
  '高崇阳',
  '丁延青',
  '王德志',
  '冷振天',
  '刘俊文',
  '李高阳',
  '梁冲',
  '李泽',
  '肖友亮',
  '李兰芳',
  '高海涛',
  '惠京艳'
]

const generateRandomGreenMenName = () => {
  return GREEN_MEN_NAMES[randInt(0, GREEN_MEN_NAMES.length - 1)]
}

const isGreenManAttackable = (greenMan) => {
  return (!greenMan.dead && (!greenMan.resetTime || Date.now() - greenMan.resetTime > GREEN_MEN_RESET_ATTACK_TIME))
}

const GameContext = createContext()

const gameReducer = (state, action) => {

  if (action.type === 'start') {
    return {
      ...state,
      timer: GAME_TIME,
      status: 'playing'
    }
  }

  if (action.type === 'replay') {
    return {
      ...state,
      status: 'start',
      timer: 0,
      scores: []
    }
  }

  if (action.type === 'reset') {
    const now = Date.now()
    const greenMen = [...state.greenMen]
    return {
      ...state,
      greenMen: greenMen.map(greenMan => {
        if (greenMan.dead && now - greenMan.deadTime > GREEN_MEN_RESET_TIME) {
          return {
            ...greenMan,
            dead: false,
            deadTime: Date.now(),
            name: generateRandomGreenMenName()
          }
        }
        return greenMan
      })
    }
  }

  if (state.status !== 'playing') {
    return state
  }

  if (action.type === 'restart') {
    const timer = state.timer - 1
    if (timer <= 0) {
      return {
        ...state,
        status: 'gameover'
      }
    }
    return {
      ...state,
      timer
    }
  }

  if (action.type === 'bomb') {
    const greenMen = [...state.greenMen]

    let killed = 0

    for (let i = 0; i < greenMen.length; i++) {
      const greenMan = greenMen[i]
      if (isGreenManAttackable(greenMan)) {
        killed++
        greenMen[i] = {
          ...greenMan,
          dead: true,
          deadTime: Date.now(),
          killedBy: action.player,
          deathCause: action.type
        }
      }
    }

    const scores = [...state.scores]
    if (killed > 0) {
      const ix = scores.findIndex(o => o.username === action.player.username)
      if (ix > -1) {
        scores[ix] = {
          ...action.player,
          kills: scores[ix].kills + killed
        }
      } else {
        scores.push({
          ...action.player,
          kills: killed
        })
      }
      scores.sort((a, b) => b.kills - a.kills)
    }

    return {
      ...state,
      greenMen,
      scores
    }
  }

  if (action.type === 'like' || action.type === 'attack') {
    const greenMen = [...state.greenMen]

    const scores = [...state.scores]

    for (let i = 0; i < greenMen.length; i++) {
      const greenMan = greenMen[i]
      if (isGreenManAttackable(greenMan) &&
        (action.type === 'like' || greenMan.name === action.name.toLowerCase())) {
        greenMen[i] = {
          ...greenMan,
          dead: true,
          deadTime: Date.now(),
          killedBy: action.player,
          deathCause: action.type
        }

        const ix = scores.findIndex(o => o.username === action.player.username)
        if (ix > -1) {
          scores[ix] = {
            ...action.player,
            kills: scores[ix].kills + 1
          }
        } else {
          scores.push({
            ...action.player,
            kills: 1
          })
        }
        scores.sort((a, b) => b.kills - a.kills)

        return {
          ...state,
          greenMen,
          scores
        }
      }
      // if (greenMan.name === action.name) {
      //   greenMan.dead = true
      //   greenMan.deadBy = action.player
      //   break
      // }
    }
  }

  return state
}

export const GameProvider = ({children}) => {

  const [gameState, dispatch] = useReducer(gameReducer, {
    status: 'start', // start, playing, gameover
    timer: 0,
    greenMen: [
      ...Array(GREEN_MEN_COUNT)
        .fill(0)
        .map((_, i) => ({
          name: generateRandomGreenMenName()
        }))
    ], // 小绿人集合
    scores: []
  })

  const {greenMen, timer, status, scores} = gameState


  const setupGame = async () => {
    await insertCoin({liveMode: 'tiktok'})
    onTikTokLiveEvent((event) => {
      // console.log('tiktok live event', event)
      // addCard(event.type, '@' + event.data.username, event.data.userPhotourl, event.data.comment)

      const player = {
        username: event.data.username,
        userPhotoUrl: event.data.userPhotoUrl
      }

      switch (event.type) {
        case 'chat':
          dispatch({
            type: 'attack',
            player,
            name: event.data.comment // 传入用户输入的内容
          })
          break
        case 'gift':
          dispatch({
            type: 'bomb',
            player
          })
          break
        case 'like':
          dispatch({
            type: 'like',
            player
          })
          break
      }

    })
  }

  // 重启游戏
  useEffect(() => {
    const gameLoop = setInterval(() => {
      // console.log('aaaaaaaaaaaaaaaaaa' + Date.now())
      dispatch({type: 'restart'})
    }, 1000)
    return () => clearInterval(gameLoop)
  }, [])

  // 重置绿人
  useEffect(() => {
    // const gameRestart = setInterval(() => {
    //   console.log('aaaaaaaaaaaaaaaaaa' + Date.now())
    //   dispatch({type: 'restart'})
    // }, 1000)
    const gameLoop = setInterval(() => {
      dispatch({type: 'reset'})
    }, 100)
    return () => {
      // clearInterval(gameRestart)
      clearInterval(gameLoop)
    }
  }, [])

  useEffect(() => {
    if (!DEBUG_MODE) {
      setupGame()
    }
  }, [])

  return <GameContext.Provider value={{
    dispatch,
    greenMen,
    timer,
    status,
    scores
  }}>{children}</GameContext.Provider>
}

export const useGame = () => {
  const context = useContext(GameContext)
  if (context === undefined) {
    throw new Error('useGame must be used within a GameProvider')
  }
  return context
}
